#pragma once
#ifndef xShader_h__
#define xShader_h__
#include "xRes.h"
namespace Sky
{
	class xEffect : public xDeviceRes<LPD3DXEFFECT>
	{
	public:
		static TVoid StaticInit(TUint D3DXSHADER_ = 0)
		{
			ms_Flags = D3DXSHADER_;
		}
	public:
		xEffect();
		~xEffect();
	protected:
		virtual TResult onCreate(xDxApp* app);
		virtual TResult onDelete(xDxApp* app);
		//xRes
		virtual TResult onCreate(xDevice* device);
		virtual TResult onReset(xDevice* device) ;
		virtual TResult onLost(xDevice* device);
		virtual TResult onDelete(xDevice* device);
	private:
		TVoid Initialise();
		TVoid Finalise();
	public:
		static const TUint From_Create	=	0x00000000;
		static const TUint From_File	=	0x00000001;
		static const TUint From_Module	=	0x00000002;
		static const TUint From_Ex		=	0x10000000;
		////xPict& setSrcFile(TChar* fileName,TBool isConstStatic = vFalse){m_srcFile.Set(fileName,isConstStatic);m_Type |= From_File;return *this;}
	public:
		xEffect& setSrcFile(StringPtr& fileName,TBool isConstStatic = vFalse){m_srcFile = fileName;m_Type |= From_File;return *this;}
		xEffect& setDefines(){return *this;}
		xEffect& setInclude(){return *this;}
		xEffect& setFlags(TUint D3DXSHADER_ = 0){m_Flags = D3DXSHADER_;return *this;}
		xEffect& setPool(){return *this;}
		LPD3DXEFFECT getEffect(){return getCreatedRes();}
	private:
		static TUint ms_Flags;
	private:
		StringPtr	 m_srcFile;
		TUint	 m_Type;
		TUint	 m_Flags;
	};
	
	/*/////////////////////////////////////////////////////////////////////////
#define ShaderConstantType(type,len)	\
	class ShaderReg_##type_##len		\
	{									\
	public:								\
		typedef type value_type[len];	\
		enum{value_length = len};		\
		void operator = (const type& v){}	\
		void operator = (const value_type& v){}					\
		const static TAchar* GetType(){return ""#type;}			\
		int GetSize(){return value_length * sizeof(type);}		\
		int GetIndex(){return _index;}							\
		int GetLength(){return value_length;}					\
		ShaderReg_##type_##len(const TAchar* key):_key(key){}	\
		ShaderReg_##type_##len():_key(vNull){}					\
	private:													\
		int			_index;										\
		const char* _key;										\
	}
#define ShaderConstantTypeAndName(type,len,name)			\
	class ShaderReg_##type##_##len##_##name					\
	{														\
	public:													\
		typedef type value_type[len];							\
		enum{value_length = len};								\
		void operator = (const type& v){}						\
		void operator = (const value_type& v){}					\
		const static TAchar* GetType(){return ""#type;}			\
		int GetSize(){return value_length * sizeof(type);}		\
		int GetIndex(){return _index;}							\
		int GetLength(){return value_length;}					\
		ShaderReg_##type##_##len##_##name:_key(""#name){}		\
	private:													\
		int			_index;										\
		const char* _key;										\
	}
	//////////////////////////////////////////////////////////////////////////
	class xShaderConstant
	{
	public:
		typedef ShaderConstantTypeAndName(Matrix,1,matrix_world)						matrix_world;
		typedef ShaderConstantTypeAndName(Matrix,1,matrix_inverse_world)				matrix_inverse_world;
		typedef ShaderConstantTypeAndName(Matrix,1,matrix_transpose_world)				matrix_transpose_world;
		typedef ShaderConstantTypeAndName(Matrix,1,matrix_inverse_transpose_world)		matrix_inverse_transpose_world;
	};*/

	class xHLSLShader : public xDeviceRes<IUnknown*>
	{
	
	private:
		static const TUint From_File	=	0x00000001;
		static const TUint From_Mem		=	0x00000002;
		static const TUint From_Module	=	0x00000004;
	protected:
		virtual TResult onCreate(xDxApp* app);
		virtual TResult onDelete(xDxApp* app);
		//xRes
		virtual TResult onCreate(xDevice* device);
		virtual TResult onReset(xDevice* device);
		virtual TResult onLost(xDevice* device);
		virtual TResult onDelete(xDevice* device);
	public:

	public:
		xHLSLShader& setSrcFile(StringPtr& srcFile,TBool isConstStatic = vFalse){m_srcFile = srcFile;m_Type |= From_File;return *this;};
		//xShader& setNamedConstant(TChar* name,TFloat val){m_diffuseConstTable->SetFloat();};
		//xHLSLShader& setSrcData(TChar* srcData,TInt size){m_srcData = data;m_srcSize = size;m_Type |= From_Mem;return *this;};
	private:
		StringPtr m_srcFile;
		TChar*	 m_srcData;
		TUint	 m_srcSize;
		TUint		m_Type;
		ID3DXConstantTable*     m_ConstTable;
	};


	class xVertexShader : public xHLSLShader
	{
	public:
		LPDIRECT3DVERTEXSHADER9 getVertexShader(){return m_VertexShader;}
		TBool	attach(xHLSLShader* shader);
		TVoid	detach();
	private:
		LPDIRECT3DVERTEXSHADER9 m_VertexShader;
	};
	class xPixelShader : public xHLSLShader
	{
	public:
	private:
		LPDIRECT3DPIXELSHADER9  m_PixelShader;
	};
}
#endif // xShader_h__